package com.gopay.bis.web.controller;

import java.math.BigDecimal;
import java.util.Random;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.gopay.remote.bank.ScanPayInteractRemoteService;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.gopay.bis.manager.bank.scan.CmbcWechatScanPayManager;
import com.gopay.bis.manager.bank.scan.WechatScanPayManager;
import com.gopay.bis.service.bank.impl.scan.AlipayScanPayCmbcSericeImpl;
import com.gopay.bis.service.bank.impl.scan.CmbcWechatScanPayServiceImpl;
import com.gopay.bis.service.bank.impl.scan.WechatScanPayServiceImpl;
import com.gopay.bis.service.bank.impl.scan.WechatSdkPayServiceImpl;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.ScanPayBaseMessage;
import com.gopay.common.domain.bank.wechat.scan.cmbc.FetchCheckAccntFile;
import com.gopay.common.domain.bank.wechat.scan.cmbc.FileDownReq;
import com.gopay.common.domain.bank.wechat.scan.cmbc.MerchantModify;
import com.gopay.common.domain.bank.wechat.scan.cmbc.MerchantQuery;
import com.gopay.common.domain.bank.wechat.scan.cmbc.MerchantSettled;
import com.gopay.common.domain.bank.wechat.scan.req.ScanOrderQueryReqMsg;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.ResponseUtils;
import com.gopay.common.util.spring.SpringContextUtil;
import com.gopay.remote.bank.ScanPayMerchantService;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

@Controller
@RequestMapping(value = "/wechat")
public class WechatTest {

	private static Logger logger = LoggerFactory.getLogger(WechatTest.class);

	private static final String SDK_NOTIFY_URL = "https://bisbank.gopay.com.cn/WechatSdkPayServerRes.shtml";
	private static final String SCAN_NOTIFY_URL = "https://bisbank.gopay.com.cn/WechatScanPayServerRes.shtml";

	@Resource(name = "WECHAT-SDK")
	private ScanPayInteractRemoteService wechatSdk;
	@Resource(name = "WECHAT-SCAN")
	private ScanPayInteractRemoteService wechatScan;
	@Resource(name = "wechatScanPayManager")
	private WechatScanPayManager wechatScanPayManager;

	// 商户入驻测试
	@Resource(name = "scanPayMerchantService")
	private ScanPayMerchantService scanPayMerchantService;

	private static long seed = 0;

	private static int seq = 0;

	@RequestMapping(value = "/pay", method = { RequestMethod.GET })
	public void pay(HttpServletRequest request, HttpServletResponse response) {
		String operater = request.getParameter("operator");
		logger.error("=============operater:" + operater + "===================");
		ScanPayBaseMessage scanPayMsg = new ScanPayBaseMessage();
		scanPayMsg.setDeviceInfo("info");
		scanPayMsg.setMchCreateIp("127.0.0.1");
		scanPayMsg.setLimitCreditPay("0");
		scanPayMsg.setProductId("001");
		scanPayMsg.setGoodsBody("goapy-wechat");
		scanPayMsg.setGoodsTag("test");
		scanPayMsg.setOrderDate("20160811053947");
		scanPayMsg.setAmount(new BigDecimal("0.01"));
		scanPayMsg.setOrderId(creatSerialNumber(16));
		scanPayMsg.setOrderId(creatSerialNumber(16));
		scanPayMsg.setBankIntrChann(BisBankInterfaceChannel._15);
		scanPayMsg.setBank("WECHAT");
		scanPayMsg.setOutStlmCd("WECHAT");
		scanPayMsg.setPayUrl("https://pay.swiftpass.cn/pay/gateway");
		scanPayMsg.setQueryUrl("https://pay.swiftpass.cn/pay/gateway");
		scanPayMsg.setRefundUrl("https://pay.swiftpass.cn/pay/gateway");
		scanPayMsg.setRefundQueryUrl("https://pay.swiftpass.cn/pay/gateway");

		try {
			if ("sdk".equals(operater)) {
				logger.error("*********当前操作为sdk支付");
				scanPayMsg.setMerID("100550019451");
				scanPayMsg.setOrderId("20160813144159");
				scanPayMsg.setBankBusProd(BisBankBusinessProd._17);
				scanPayMsg.setPayRuturnUrl(SDK_NOTIFY_URL);
				Result res = wechatSdk.pay(scanPayMsg);
				logger.error("********sdk支付返回结果:" + ToStringBuilder.reflectionToString(res));
				String result = toXml(res);
				ResponseUtils.renderText(response, result);
			} else if ("scan".equals(operater)) {
				scanPayMsg.setMerID("100550019451");
				logger.error("########当前操作为扫码支付");
				scanPayMsg.setBankBusProd(BisBankBusinessProd._16);
				scanPayMsg.setPayRuturnUrl(SCAN_NOTIFY_URL);
				Result res = wechatScan.pay(scanPayMsg);
				logger.error("########扫码支付返回结果:" + ToStringBuilder.reflectionToString(res));
				String result = toXml(res);
				ResponseUtils.renderText(response, result);
			} else {
				logger.error("【parameter false】");
			}

		} catch (GopayException e) {
			e.printStackTrace();
		}
	}

	@RequestMapping(value = "/refund", method = { RequestMethod.GET })
	public void refund(HttpServletRequest request, HttpServletResponse response) {
		String oriOrderId = request.getParameter("orderId");
		logger.info("退款=========民生扫码退款原订单号 :" + oriOrderId + "========");
		CmbcWechatScanPayManager manager = (CmbcWechatScanPayManager) SpringContextUtil
				.getBean("cmbcWechatScanPayManager");
		BaseMessage msg = new BaseMessage();
		msg.setPrivateKeyPath("/usr/local/ciecc/bankcerts/CMBC/cmbc_scan_gfb_pkcs8_rsa_private_key_2048.pem");
		msg.setPublicKeyPath("/usr/local/ciecc/bankcerts/CMBC/cmbc_scan_rsa_public_key_2048.pem");
		msg.setPayUrl("http://110.80.39.174:9013/nbp-smzf-hzf");
		msg.setTkOriOrderId(oriOrderId);
		msg.setAmount(new BigDecimal("0.01"));
		try {
			Object res = manager.refund(msg);
			logger.info("refund response : " + ToStringBuilder.reflectionToString(res));
			ResponseUtils.renderText(response, ToStringBuilder.reflectionToString(res));
		} catch (GopayException e) {
			e.printStackTrace();
		}
		/*
		 * ScanPayBaseMessage scanPayMsg = new ScanPayBaseMessage();
		 * scanPayMsg.setPayUrl("https://pay.swiftpass.cn/pay/gateway");
		 * scanPayMsg.setQueryUrl("https://pay.swiftpass.cn/pay/gateway");
		 * scanPayMsg.setRefundUrl("https://pay.swiftpass.cn/pay/gateway");
		 * scanPayMsg.setRefundQueryUrl("https://pay.swiftpass.cn/pay/gateway");
		 * scanPayMsg.setMerID("100550019451");
		 * scanPayMsg.setBankOrderId(request.getParameter("bankorderid"));
		 * scanPayMsg.setAmount(new BigDecimal(request.getParameter("amount")));
		 * try{ if("scan".equals(operater)){ logger.info(
		 * "  -----scan refund----"); ScanRefundReqMsg message = new
		 * ScanRefundReqMsg(); BeanUtils.copyProperties(scanPayMsg,message);
		 * message.setRefund_channel(request.getParameter("refundtype"));
		 * ScanRefundResMsg res = (ScanRefundResMsg)
		 * wechatScanPayManager.refund(message); logger.info(
		 * "-------scan refund return res:"
		 * +ToStringBuilder.reflectionToString(message)); String text
		 * =toXml(res); ResponseUtils.renderText(response, text); } }catch
		 * (GopayException e) { e.printStackTrace(); }
		 */

	}

	@RequestMapping(value = "/refundQuery", method = { RequestMethod.GET })
	public void refundQuery(HttpServletRequest request, HttpServletResponse response) {
		String oriOrderId = request.getParameter("orderId");
		logger.info("退款查询=========民生扫码退款原订单号 :" + oriOrderId + "========");
		AlipayScanPayCmbcSericeImpl manager = (AlipayScanPayCmbcSericeImpl) SpringContextUtil
				.getBean("ALIPAY-SCAN-CMBC");
		BaseMessage msg = new BaseMessage();
		msg.setPrivateKeyPath("/usr/local/ciecc/bankcerts/CMBC/cmbc_scan_gfb_pkcs8_rsa_private_key_2048.pem");
		msg.setPublicKeyPath("/usr/local/ciecc/bankcerts/CMBC/cmbc_scan_rsa_public_key_2048.pem");
		msg.setPayUrl("http://110.80.39.174:9013/nbp-smzf-hzf");
		msg.setTkOriOrderId(oriOrderId);
		msg.setBankOrderId(oriOrderId);
		msg.setOrderId(oriOrderId);
		try {
			Result res = manager.refundQuery(msg);
			logger.info("refund response : " + ToStringBuilder.reflectionToString(res));
			ResponseUtils.renderText(response, ToStringBuilder.reflectionToString(res));
		} catch (GopayException e) {
			e.printStackTrace();
		}
		/*
		 * String operater = request.getParameter("operator");
		 * logger.info("=========operator:"+operater+"========");
		 * ScanPayBaseMessage scanPayMsg = new ScanPayBaseMessage();
		 * scanPayMsg.setPayUrl("https://pay.swiftpass.cn/pay/gateway");
		 * scanPayMsg.setQueryUrl("https://pay.swiftpass.cn/pay/gateway");
		 * scanPayMsg.setRefundUrl("https://pay.swiftpass.cn/pay/gateway");
		 * scanPayMsg.setRefundQueryUrl("https://pay.swiftpass.cn/pay/gateway");
		 * scanPayMsg.setMerID("100550019451");
		 * scanPayMsg.setBankOrderId(request.getParameter("bankorderid"));
		 * scanPayMsg.setAmount(new BigDecimal(request.getParameter("amount")));
		 * try{ if("scan".equals(operater)){ logger.info(
		 * "----- scan refundQuery-----"); ScanRefundQueryReqMsg message = new
		 * ScanRefundQueryReqMsg();
		 * BeanUtils.copyProperties(scanPayMsg,message); ScanRefundQueryResMsg
		 * resMsg = (ScanRefundQueryResMsg)
		 * wechatScanPayManager.refundQuery(message); logger.info(
		 * "------scan refundQuery return res:"
		 * +ToStringBuilder.reflectionToString(message)); String text
		 * =toXml(resMsg); ResponseUtils.renderText(response, text); } }catch
		 * (GopayException e) { e.printStackTrace(); }
		 */
	}

	@RequestMapping(value = "/query", method = { RequestMethod.GET })
	public void query(HttpServletRequest request, HttpServletResponse response) {
		String operater = request.getParameter("operator");
		logger.error("=============operater:" + operater + "===================");
		ScanPayBaseMessage scanPayMsg = new ScanPayBaseMessage();
		scanPayMsg.setDeviceInfo("info");
		scanPayMsg.setMchCreateIp("127.0.0.1");
		scanPayMsg.setLimitCreditPay("0");
		scanPayMsg.setProductId("001");
		scanPayMsg.setGoodsBody("测试购买商品");
		scanPayMsg.setGoodsTag("test");
		scanPayMsg.setOrderDate("2016-08-11");
		scanPayMsg.setOrderId("1470794639533");
		scanPayMsg.setPayUrl("https://pay.swiftpass.cn/pay/gateway");
		scanPayMsg.setQueryUrl("https://pay.swiftpass.cn/pay/gateway");
		scanPayMsg.setRefundUrl("https://pay.swiftpass.cn/pay/gateway");
		scanPayMsg.setRefundQueryUrl("https://pay.swiftpass.cn/pay/gateway");
		scanPayMsg.setMerID("100550019451");
		try {
			if ("sdk".equals(operater)) {
				logger.error("*********当前操作为sdk查询");
				scanPayMsg.setOrderId("20160813144159");
				scanPayMsg.setBankOrderId("20160813144159");
				scanPayMsg.setBank(BankConstants.BANK_LOGO_WECHAT);
				scanPayMsg.setBankBusProd(BisBankBusinessProd._17);
				Result res = wechatSdk.orderQuery(scanPayMsg);
				logger.error("********sdk查询返回结果:" + ToStringBuilder.reflectionToString(res));
				String result = toXml(res);
				ResponseUtils.renderText(response, result);
			} else if ("scan".equals(operater)) {
				ScanOrderQueryReqMsg rer = (ScanOrderQueryReqMsg) scanPayMsg;
				rer.setOrderId("1363741572");
				rer.setBankOrderId("1363741572");
				rer.setBank(BankConstants.BANK_LOGO_WECHAT);
				rer.setBankBusProd(BisBankBusinessProd._16);
				rer.setFront(false);
				logger.error("########当前操作为扫码查询");
				Result res = wechatScan.orderQuery(scanPayMsg);
				logger.error("########扫码查询返回结果:" + ToStringBuilder.reflectionToString(res));
				String result = toXml(res);
				ResponseUtils.renderText(response, result);
			} else {
				logger.error("【parameter false】");
			}
		} catch (GopayException e) {
			e.printStackTrace();
		}
	}

	@RequestMapping(value = "/merchantSettled", method = { RequestMethod.GET })
	public void merchantSettled(HttpServletRequest request, HttpServletResponse response) {
		// 支付通道
		String payWay = request.getParameter("payWay");
		if (StringUtils.equals("0", payWay)) {
			payWay = "WXZF";
		} else if (StringUtils.equals("1", payWay)) {
			payWay = "ZFBZF";
		} else {
			logger.info("---{ 不支持的入驻通道,payWay参数为0-WXZF、1-ZFBZF }-----");
			ResponseUtils.renderText(response, "不支持的入驻通道,payWay参数为0-WXZF、1-ZFBZF");
			return;
		}
		// 合作方商户编码
		String merchantId = generateReqSeq(4);
		// 商户名称
		String merchantName = "国付宝测试0_" + seq;
		// 商户简称
		String shortName = "测试0_" + seq;
		// 商户地址
		String merchantAddress = "北京雍和宫航天园";
		// 科服电话
		String servicePhone = "400-0550-009";
		// 经营类目
		String category = "";
		if (StringUtils.equals("WXZF", payWay)) {
			category = "203";
		} else {
			category = "2015091000058486";
		}
		MerchantSettled req = new MerchantSettled();
		req.setPayWay(payWay);
		req.setMerchantId(merchantId);
		req.setMerchantName(merchantName);
		req.setShortName(shortName);
		req.setMerchantAddress(merchantAddress);
		req.setServicePhone(servicePhone);
		req.setCategory(category);
		try {
			Result res = scanPayMerchantService.merchantSettled(req);
			logger.info("测试商户入驻：商户编码--" + merchantId + "; 入驻通道 ：" + payWay);
			logger.info("商户入驻返回信息 ：" + ToStringBuilder.reflectionToString(res.getDefaultModel()));
			ResponseUtils.renderText(response, ToStringBuilder.reflectionToString(res.getDefaultModel()));
		} catch (GopayException e) {
			e.printStackTrace();
		}
		// 商户每入驻一次，序号递增
		seq++;
	}

	@RequestMapping(value = "/merchantQuery", method = { RequestMethod.GET })
	public void merchantQuery(HttpServletRequest request, HttpServletResponse response) {
		// 商户编码
		String merchantId = request.getParameter("merchantId");
		MerchantQuery req = new MerchantQuery();
		req.setMerchantId(merchantId);
		try {
			Result res = scanPayMerchantService.merchantQuery(req);
			logger.info("商户查询返回信息 ：" + ToStringBuilder.reflectionToString(res.getDefaultModel()));
			ResponseUtils.renderText(response, ToStringBuilder.reflectionToString(res.getDefaultModel()));
		} catch (GopayException e) {
			e.printStackTrace();
		}
	}

	@RequestMapping(value = "/merchantModify", method = { RequestMethod.GET })
	public void merchantModify(HttpServletRequest request, HttpServletResponse response) {
		// 商户编码
		String merchantId = request.getParameter("merchantId");
		MerchantModify req = new MerchantModify();
		req.setMerchantId(merchantId);
		req.setMerchantAddress("北京" + new Random(100).nextInt() + "元桥");
		req.setServicePhone("010-0550-00" + new Random(10).nextInt());
		String contactName = modify(3);
		req.setContactName(contactName);
		try {
			logger.info("商户编码：" + merchantId + "; 修改的联系人名称为：" + contactName);
			Result res = scanPayMerchantService.merchantModify(req);
			logger.info("商户修改返回信息 ：" + res.getDefaultModel());
			String md = StringUtils.substringAfter(ToStringBuilder.reflectionToString(res.getDefaultModel()), "[");
			md = md.replaceAll("]", "");
			String mdMsg = "修改的商户信息:<br/>" + md + "<br/><br/><br/>";
			response.getWriter().write(mdMsg);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@RequestMapping(value = "/getCheckAccountFile", method = { RequestMethod.GET })
	public void getCheckAccountFile(HttpServletRequest request, HttpServletResponse response) {
		try {
			FileDownReq obj=new FileDownReq();
			obj.setDate("20161018");
			obj.setFileType("1");
			obj.setChannel("17");
			Result res = scanPayMerchantService.getCheckAccountFile(obj );
			FetchCheckAccntFile file = (FetchCheckAccntFile) res.getDefaultModel();
			logger.info("-----------对账日日:20161018----------");
			logger.info("返回对账文件内容为 ：" + file.getContent());
			ResponseUtils.renderText(response, "对账日日:20161018；返回对账文件内容为 ：<br/>" + file.getContent());
		} catch (GopayException e) {
			e.printStackTrace();
		}
	}

	public static String generateReqSeq(int size) {
		StringBuilder key = new StringBuilder();
		String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		for (int i = 0; i < size; i++) {
			int index = (int) (Math.random() * (chars.length() - 1));
			key.append(chars.charAt(index));
		}
		return new DateTime().toString("yyyyMMddHHmm") + key.toString();
	}

	public static String modify(int size) {
		StringBuilder key = new StringBuilder();
		String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		for (int i = 0; i < size; i++) {
			int index = (int) (Math.random() * (chars.length() - 1));
			key.append(chars.charAt(index));
		}
		return key.toString();
	}

	/**
	 * @Description: 穿件随机字符串
	 * @param length
	 * @return
	 * @author w_jiqing
	 */
	public static String creatSerialNumber(int length) {
		byte[] randomSerial = new byte[length];
		String charactors = "123456789";
		int charSetLength = charactors.length();
		seed = seed ^ System.currentTimeMillis();
		java.util.Random randomNumber = new java.util.Random(seed);

		for (int i = 0; i < length; i++) {
			randomNumber.setSeed(seed);
			int j = (int) (randomNumber.nextFloat() * charSetLength);
			randomSerial[i] = (byte) charactors.charAt(j);
			seed = seed ^ randomNumber.nextInt();
		}
		return (new String(randomSerial));
	}

	public String toXml(Object obj) {
		// XStream xstream=new XStream();
		// XStream xstream=new XStream(new DomDriver()); //直接用jaxp dom来解释
		// 指定编码解析器,直接用jaxp dom来解释
		XStream xstream = new XStream(new DomDriver("GBK"));

		xstream.processAnnotations(obj.getClass());
		return xstream.toXML(obj);
	}

}
